#include "qanimateswidget.h"

QAnimateSWidget::QAnimateSWidget(QWidget *parent) :
    QStackedWidget(parent)
{
    isAnimation = false;
    duration = 1000;
    animation = new QPropertyAnimation(this, QByteArray());
    connect(animation, SIGNAL(valueChanged(QVariant)), this, SLOT(valueChanged_slot(QVariant)));
    connect(animation, SIGNAL(finished()), this, SLOT(animationFinished()));
}

QAnimateSWidget::~QAnimateSWidget()
{
    if( animation )
    {
        delete animation;
        animation = NULL;
    }
}

void QAnimateSWidget::valueChanged_slot(QVariant value)
{
    currentValue = value;
    update();
}

void QAnimateSWidget::setDuration(int d)
{
    duration = d;
}

void QAnimateSWidget::paintEvent(QPaintEvent *e)
{
    if( isAnimation )
    {
        QPainter paint(this);
        switch( direction )
        {
        case UptoDown:
            //绘制当前Widget
            paintPrevious(paint, currentIndex());
            //绘制下一个widget
            paintNext(paint, nextIndex);
            break;
        case DowntoUp:
            //绘制当前Widget
            paintPrevious(paint, nextIndex);
            //绘制下一个widget
            paintNext(paint, currentIndex());
            break;
        }

    }
}

void QAnimateSWidget::paintNext(QPainter &paint, int nextIndex)
{
    double  val = currentValue.toDouble();
    QWidget *w = widget(nextIndex);
    QPixmap pixmap(w->size());
    w->render(&pixmap);
    QPixmap temp(pixmap.size());
    temp.fill(Qt::transparent);
    QPainter pter(&temp);
    pter.setCompositionMode(QPainter::CompositionMode_Source);
    pter.drawPixmap(0, 0, pixmap);
    pter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    pter.fillRect(temp.rect(), QColor(0, 0, 0, 255*val/100));
    pter.end();
    pixmap = temp;
    paint.drawPixmap(0,0, pixmap);

}

void QAnimateSWidget::paintPrevious(QPainter &paint, int currentIndex)
{
    double  val = currentValue.toDouble();
    QWidget *w = widget(currentIndex);
    QPixmap pixmap(w->size());
    w->render(&pixmap);
    QPixmap temp(pixmap.size());
    temp.fill(Qt::transparent);
    QPainter pter(&temp);
    pter.setCompositionMode(QPainter::CompositionMode_Source);
    pter.drawPixmap(0, 0, pixmap);
    pter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    pter.fillRect(temp.rect(), QColor(0, 0, 0, 255*(100 - val)/100));
    pter.end();
    pixmap = temp;
    paint.drawPixmap(0,0, pixmap);
}

void QAnimateSWidget::next()
{
    if( isAnimation )
        {
            return;
        }
        isAnimation = true;
        int c = currentIndex();
        nextIndex = c + 1;
        direction = UptoDown;
        //settings;
        animation->setStartValue(0);
        animation->setEndValue(100);
        animation->setDuration(duration);
        animation->start();
}

void QAnimateSWidget::forward()
{
    if( isAnimation )
        {
            return;
        }
        isAnimation = true;
        int c = currentIndex();
        nextIndex = c - 1;
        direction = DowntoUp;
        //settings;
        animation->setStartValue(0);
        animation->setEndValue(100);
        animation->setDuration(duration);
        animation->start();
}

void QAnimateSWidget::animationFinished()
{
    isAnimation = false;
    widget(currentIndex())->show();
    setCurrentIndex(nextIndex);
}
